//
// Author: Vladimir Migashko <migashko@gmail.com>, (C) 2011
//
// Copyright: See COPYING file that comes with this distribution
//
#ifndef HITLIST_HIT_COUNTS_MEHTOD_HPP
#define HITLIST_HIT_COUNTS_MEHTOD_HPP

#include <fas/adv/json_rpc3/method.hpp>
#include "hit_counts_json.hpp"
#include "ihitlist.hpp"
#include "tags.hpp"


namespace aa = ::fas::aop;
namespace ap = ::fas::pattern;
namespace ad = ::fas::adv;
namespace ajr = ::fas::adv::json_rpc3;

/** @brief Метод "hit_counts" json-rpc аспекта соединия
 *
 * Добавляется в аспект соединения с групповым тегом _gmethod_,
 * чтобы мог быть вызван аспектом json-rpc по имени, возращаемом 
 * методом name()
 */
struct hit_counts_method
{
  ihitlist* hitlist;

  hit_counts_method(): hitlist(0) {}

  /// имя метода json-rpc
  const char *name() const { return "hit_counts"; }

  /// тип входящего запроса на вызов метода (json)
  typedef aj::value<user_id_t > invoke_request;
  /// тип ответа на входящий запрос (json)
  typedef hit_counts_json invoke_response;

  /// тип входящего уведомления (json)
  typedef aj::value<user_id_t > invoke_notify;
  /// тип исходящего уведомления (json)
  typedef hit_counts_json call_notify;

  /// Обработка входящего запроса
  /** @param t - контекст вызова (ссылка на объект соединения )
    * @param first_id - запрос 
    * @param id - идентификатор вызова метода
    * @param h - ответ
    * @return true - если ответ готов (всегда);
    */
  template<typename T>
  bool request(T& t, user_id_t  first_id, int id, hit_counts& h )
  {
    h.hits_d = hitlist->hits_day(first_id);
    h.hosts_d = hitlist->hosts_day(first_id);
    h.hits_m = hitlist->hits_month(first_id);
    h.hosts_m = hitlist->hosts_month(first_id);
    /// сообщаем что ответ готов
    return true;
  }

  /// Обработка входящего уведомления
  /** @param t - контекст вызова (ссылка на объект соединения )
    * @param first_id - запрос
    */
  template<typename T>
  void notify(T& t, user_id_t first_id )
  {
    hit_counts h;
    h.hits_d = hitlist->hits_day(first_id);
    h.hosts_d = hitlist->hosts_day(first_id);
    h.hits_m = hitlist->hits_month(first_id);
    h.hosts_m = hitlist->hosts_month(first_id);
    /// Отправляем уведомление в ответ
    t.get_aspect().template get<_hit_counts_>().notify(t, h);
  }
};

typedef aa::tag_list_n<
  aa::tag<_hit_counts_>,
  aa::gtag< ajr::_gmethod_ >
>::type hit_counts_method_tag_list;

typedef aa::advice<
      hit_counts_method_tag_list,
      ajr::method<hit_counts_method>
    >
hit_counts_method_advice;



#endif
